package org.acghub.mtdb.core;

import java.util.Collection;
import java.util.concurrent.Callable;

/**
 * 事务操作, 存储过程接口
 *
 * @author zhouhe
 */
@SuppressWarnings("unchecked")
public interface Procedure<P extends Procedure> extends Callable<Procedure.Result> {

    int MAX_RETRY_DELAY_MS = 1000 * 60;
    int MAX_RETRY_TIMES = 10;

    /**
     * 事务操作名称
     */
    String name();

    /**
     * 重试延迟, 单位ms, <=0: 立即执行
     */
    int retryDelay();

    /**
     * 重试次数, <=0:不重试
     */
    int retryTimes();

    /**
     * 执行器key, 默认使用默认执行器
     */
    Object executorKey();

    /**
     * 所在的执行器
     */
    ProcedureExecutor executor();

    /**
     * 添加监听器
     */
    P addListener(ProcedureListener<P> listener);

    /**
     * 添加监听器
     */
    P addListeners(Collection<ProcedureListener<P>> listeners);

    Collection<ProcedureListener<P>> getListeners();

    /**
     * 执行事务操作
     */
    boolean process() throws Exception;

    /**
     * 注意！！！
     * 注意！！！
     * 注意！！！
     * 直接调用call 不会触发listeners, call用于事务内嵌套调用。
     *
     * @return
     */
    @Override
    Result call();

    void execute();

    ProcedureFuture<P> submit();

    interface Result {
        boolean isSuccess();

        Throwable getCause();
    }

    @FunctionalInterface
    interface ProcedureListener<P extends Procedure> {
        void onResult(P procedure, Result result);
    }

    static <P extends Procedure> Result call(P p) {
        return p.call();
    }

    static <P extends Procedure> void execute(P p) {
        p.execute();
    }

    static <P extends Procedure> ProcedureFuture<P> submit(P p) {
        return p.submit();
    }


}
